﻿using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media.Imaging;
using RssReaderTemplate.Model;
using Microsoft.Phone.Reactive;
using System;

namespace RssReaderTemplate.UserControls
{
    public partial class RssViewer : UserControl
    {
        public RssViewer()
        {
            InitializeComponent();
        }
        public string ItemContent
        {
            get { return (string)GetValue(ItemContentProperty); }
            set
            {
                SetValue(ItemContentProperty, value);
            }
        }

        static void ItemContentChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            var viewer = (sender as RssViewer);
            viewer.ProcessContent(args.NewValue as string);
        }

        // Using a DependencyProperty as the backing store for ItemContent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemContentProperty =
            DependencyProperty.Register("ItemContent", typeof(string), typeof(RssViewer), new PropertyMetadata(null, RssViewer.ItemContentChanged));



        public Style TextStyle
        {
            get { return (Style)GetValue(TextStyleProperty); }
            set { SetValue(TextStyleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TextStyle.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextStyleProperty =
            DependencyProperty.Register("TextStyle", typeof(Style), typeof(RssViewer), null);



        public Style ImagesStyles
        {
            get { return (Style)GetValue(ImagesStylesProperty); }
            set { SetValue(ImagesStylesProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ImagesStyles.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ImagesStylesProperty =
            DependencyProperty.Register("ImagesStyles", typeof(Style), typeof(RssViewer), null);



        private void ProcessContent(string value)
        {
            var itemContent = new RssItemContent(value);
            itemContent.Contents.ToObservable(Scheduler.ThreadPool).ObserveOnDispatcher().Subscribe(item =>
                {
                    if (item is AggregatedTextFragments)
                    {
                        int textLength = 0;
                        TextBlock block = new TextBlock()
                        {
                            Style = TextStyle,
                            TextWrapping = TextWrapping.Wrap
                        };
                        block.TextWrapping = TextWrapping.Wrap;
                        foreach (var fragment in ((AggregatedTextFragments)item).TextFragments)
                        {
                            if (textLength + fragment.InnerText.Length > 1000)
                            {
                                LayoutRoot.Children.Add(block);
                                block = new TextBlock() { Style = TextStyle, TextWrapping = TextWrapping.Wrap };
                                textLength = 0;
                            }
                            textLength += fragment.InnerText.Length;
                            block.Inlines.Add(CreateInline(fragment));
                        }
                        LayoutRoot.Children.Add(block);
                    }
                    else if (item is ImageFragment)
                    {
                        Image image = new Image()
                        {
                            Source = new BitmapImage(((ImageFragment)item).Uri),
                            Style = ImagesStyles
                        };
                        LayoutRoot.Children.Add(image);
                    }
                });
            //GenerateControls(LayoutRoot, itemContent);
        }

        private void GenerateControls(StackPanel panel, RssItemContent itemContent)
        {
            foreach (var item in itemContent.Contents)
            {
                if (item is AggregatedTextFragments)
                {
                    int textLength = 0;
                    TextBlock block = new TextBlock()
                    {
                        Style = TextStyle, TextWrapping = TextWrapping.Wrap
                    };
                    block.TextWrapping = TextWrapping.Wrap;
                    foreach (var fragment in ((AggregatedTextFragments)item).TextFragments)
                    {
                        if (textLength+fragment.InnerText.Length > 2000)
                        {
                            panel.Children.Add(block);
                            block = new TextBlock() { Style = TextStyle, TextWrapping = TextWrapping.Wrap };
                            textLength = 0;
                        }
                        textLength += fragment.InnerText.Length;
                        block.Inlines.Add(CreateInline(fragment));
                    }
                    panel.Children.Add(block);
                }
                else if (item is ImageFragment)
                {
                    Image image = new Image()
                    {
                        Source = new BitmapImage(((ImageFragment)item).Uri),
                        Style = ImagesStyles
                    };
                    panel.Children.Add(image);
                }
            }
            //var grouped = GroupItemsToRender(itemContent.Contents).ToList();
            //foreach (var group in grouped)
            //{
            //    if (group.Type == "Text")
            //    {
            //        TextBlock block = new TextBlock();
            //        block.TextWrapping = TextWrapping.Wrap;
            //        foreach (var text in group.Elements.OfType<TextFragment>())
            //        {
            //            if (text != null)
            //            {
            //                block.Inlines.Add(CreateInline(text));
            //            }
            //        }
            //        panel.Children.Add(block);
            //    }
            //    if (group.Type == "Image")
            //    {
            //        foreach (var image in group.Elements.OfType<ImageFragment>())
            //        {
            //            Image img = new Image();
            //            img.Source = new BitmapImage(image.Uri);
            //            panel.Children.Add(img);
            //        }
            //    }
            //}
        }

        private IEnumerable<GroupType> GroupItemsToRender(IEnumerable<ContentFragment> fragments)
        {
            var elements = fragments.ToList();
            int i = 0;
            while (i < elements.Count)
            {
                ContentFragment header = elements[i];
                string type = GetItemType(header);
                GroupType group = new GroupType(type);
                group.Elements.Add(header);
                int j = i + 1;
                while (j < elements.Count && type == GetItemType(elements[j]))
                {
                    group.Elements.Add(elements[j]);
                    j++;
                }
                i = j;
                yield return group;
            }
            yield break;
        }

        private string GetItemType(ContentFragment item)
        {
            if (!(item is ImageFragment))
            {
                return "Text";
            }
            else
            {
                return "Image";
            }
        }

        private class GroupType
        {
            public GroupType(string type)
            {
                Type = type;
                Elements = new List<ContentFragment>();
            }

            public string Type { get; set; }
            public IList<ContentFragment> Elements { get; set; }

        }

        private Inline CreateInline(TextFragment text)
        {
            Run run = new Run();
            run.Text = text.InnerText;
            if (text.IsBold)
            {
                run.FontWeight = FontWeights.Bold;

            }
            if (text.IsItalic)
            {
                run.FontStyle = FontStyles.Italic;
            }
            return run;
        }
    }
}
